package com.example.myproject.security;

import com.example.myproject.model.User;
import com.example.myproject.utils.UserContext;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.Set;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    private String getToken(HttpServletRequest request) {
        String bearer = request.getHeader("Authorization");
        if (StringUtils.hasText(bearer) && bearer.startsWith("Bearer ")) {
            return bearer.substring(7);
        }
        return null;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {
        try {
            String token = getToken(request);
            if (token != null && jwtTokenUtil.validateToken(token)) {
                Claims claims = jwtTokenUtil.parseClaims(token);

                // 1. 安全提取用户信息
                Long userId = jwtTokenUtil.getUserIdFromToken(token);
                String username = claims.get("user_name", String.class);
                String role = validateRole(jwtTokenUtil.getUserRoleFromToken(token));

                // 2. 构建认证对象
                UserPrincipal principal = new UserPrincipal(userId, username);
                List<GrantedAuthority> authorities = Collections.singletonList(
                        new SimpleGrantedAuthority("ROLE_" + role.toUpperCase())
                );

                UsernamePasswordAuthenticationToken auth =
                        new UsernamePasswordAuthenticationToken(principal, null, authorities);

                // 3. 设置安全上下文
                SecurityContextHolder.getContext().setAuthentication(auth);
                // === 关键：设置 UserContext ===
                User user = new User();
                user.setUserId(userId);
                user.setUserName(username);
                user.setRole(role);
                UserContext.setCurrentUser(user);
            }
        } catch (JwtException e) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
            return;
        }
        chain.doFilter(request, response);
    }

    /**
     * 校验角色是否合法
     */
    private String validateRole(String rawRole) {
        if (rawRole == null) {
            return "user"; // 默认角色
        }

        // 允许的角色白名单
        Set<String> ALLOWED_ROLES = Set.of("user", "admin");

        if (!ALLOWED_ROLES.contains(rawRole.toLowerCase())) {
            throw new JwtException("Invalid role in token");
        }
        return rawRole.toLowerCase();
    }

    /**
     * 自定义用户主体对象
     */
    @Data
    @AllArgsConstructor
    public static class UserPrincipal implements Serializable {
        private Long id;
        private String username;
    }
}